#include<iostream>
#include<cstdio>
#include<cstring>
#include<unistd.h>
#include<cassert>
#include<sys/types.h>
#include<sys/wait.h>

using namespace std;
//管道是有大小的
//父进程读取，子进程写入
int main()
{
    //第一步：创建管道文件，打开读写端
    int fds[2];
    int n=pipe( fds);
    assert(n==0);

    //第二步：fork()
    pid_t id=fork();
    assert(id>=0);
    if(id==0)
    {
        //第三步：关闭fd
        //子进程进行写入
        close(fds[0]);
        //子进程的通信代码
        const char* s="我是子进程，我正在给你发消息";
        int cnt=0;
        while(true)
        {
            cnt++;
            char buffer[1024]; //只有子进程能看到
            snprintf(buffer,sizeof buffer,"child->parent say:%s[%d][%d]",s,cnt,getpid());
            //写端写满的时候，再写会阻塞，等待对方读取！
            write(fds[1] , buffer, strlen(buffer));
            //sleep(10);//每隔一秒写一次
        }
        //子进程
        close(fds[1]);
        exit(0);
    }
    //父进程
    //父进程进行写入
    close(fds[1]);
    //父进程的通信代码
    while(true)
    {
        char buffer[1024];
        // cout<<"AAAAAAAAAAAAA"<<endl;
        //如果管道中没有了数据，读端在读，默认会直接阻塞当前正在读取的进程！
        ssize_t s=read(fds[0],buffer,sizeof buffer-1);
        // cout<<"BBBBBBBBBBBBB"<<endl;
        if(s>0)    buffer[s]=0;
        cout<<" Get message # "<<buffer<<" | my pid: "<<getpid()<<endl;
        //父进程没有sleep
        break;
    }

    close(fds[0]);
    cout<<"父进程关闭读端"<<endl;

    int status=0;
    n=waitpid(id,&status,0);
    assert(n==id);
    
    cout<<"pid->"<< n <<" : "<<(status & 0x7F)<<endl;

    //3是读取[0]
    //4是写入[1]
    // cout<<"fds[0]:"<<fds[0]<<endl;
    // cout<<"fds[1]:"<<fds[1]<<endl;



    return 0;
}